#include "widget.h"
#include "ui_widget.h"
#include "filehandler.h"
#include "cryptolib.h"

/**
* @brief Der Konstruktor zu Widget
*
* Initialisiert Variablen, connectet Elemente des GUI mit Funktionen.
*/
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    // Zu verschlüsselnde Datei auswählen
    connect (ui->pbOpenFileToBeEnc,SIGNAL(clicked()),SLOT(openFileToBeEnc()));
    // Private Key Datei öffnen
    connect (ui->pbOpenFilePrivateFile,SIGNAL(clicked()),SLOT(openFilePrivateFile()));
    // GUI auf Standard zurücksetzen
    connect (ui->pbResetAll,SIGNAL(clicked()),SLOT(resetAll()));
    // GUI Verschlüsselungsoptionen zurücksetzen
    connect (ui->pbResetEncrParams,SIGNAL(clicked()),SLOT(resetEncParams()));
    // Checkbox ob die Ausgabedatei ins gleiche Verzeichnis geschrieben werden soll (passt Variablen an wenn sich der Status ändert)
    connect (ui->cbSameAsSource,SIGNAL(stateChanged(int)),SLOT(showOrHideTargetDestination()));
    // Ausgabeverzeichnis auswählen falls nicht in das gleiche Verzeichnis wie Quelle
    connect (ui->pbOpenDestination,SIGNAL(clicked()),SLOT(openDir()));
    // Verschlüsselung starten
    connect (ui->pbEncrypt,SIGNAL(clicked()),SLOT(ENCRstartEncrypt()));
    // Entschlüsselung starten
    connect (ui->pbDecrypt,SIGNAL(clicked()),SLOT(ENCRstartDecrypt()));

    // Checkbox und Variablen initialisieren
    showOrHideTargetDestination();
    // Alle GUI Einstellungen auf default ändern
    resetAll();
}

/**
* @brief Der Dekonstruktor zu Widget
*
* Entfernt das Widget aus dem Speicher.
*/
Widget::~Widget()
{
    delete ui;
}

/*!
Öffnet die Datei die ver- oder entschlüsselt werden soll.
*/
void Widget::openFileToBeEnc(void)
{
    QString filename = QFileDialog::getOpenFileName(
                this,
                tr("Open Document"),
                QDir::currentPath(),
                tr("Any (*.*)") );
    if( !filename.isNull() )
    {
        fileToBeEncrypted = filename;

        ui->LabelFileLocation->setText(Widget::fileToBeEncrypted);

        // nächsten Schritt freischalten
        ui->rbPrivateKey->setEnabled(true);
        ui->rbFileKey->setEnabled(true);
        ui->rbCaesar->setEnabled(true);
        ui->InputPrivateKey->setEnabled(true);
        ui->pbOpenFilePrivateFile->setEnabled(true);
        ui->sbCaesar->setEnabled(true);

        // Ver- und entschlüsseln freischalten, da Caesar sofort funktioniert.
        ui->pbEncrypt->setEnabled(true);
        ui->pbDecrypt->setEnabled(true);

        // Checkbox Status prüfen
        showOrHideTargetDestination();
    }
}

/*!
Öffnet die Private Key Datei die zum ver- oder entschlüsseln verwendet werden soll.
*/
void Widget::openFilePrivateFile(void)
{
    QString filename = QFileDialog::getOpenFileName(
                this,
                tr("Open Document"),
                QDir::currentPath(),
                tr("Private Key File (*.*)") );
    if( !filename.isNull() )
    {
        Widget::filePrivateFile = filename;

        ui->LabelFileLocationPrivateFile->setText(Widget::filePrivateFile);
        ui->rbFileKey->setChecked(true);

    }
}

/*!
GUI resetten
*/
void Widget::resetAll(void)
{
    resetEncParams();
    ui->rbPrivateKey->setEnabled(false);
    ui->rbFileKey->setEnabled(false);
    ui->rbCaesar->setEnabled(false);
    ui->InputPrivateKey->setEnabled(false);
    ui->pbOpenFilePrivateFile->setEnabled(false);
    ui->sbCaesar->setEnabled(false);
    ui->pbEncrypt->setEnabled(false);
    ui->pbDecrypt->setEnabled(false);
    Widget::fileToBeEncrypted = "";
    Widget::fileTargetFolder = "";
    ui->LabelFileLocation->setText("(no file selected)");
    showOrHideTargetDestination();
}

/*!
GUI Verschlüsselungsparameter resetten
*/
void Widget::resetEncParams(void)
{
    ui->InputPrivateKey->setText("");
    ui->LabelFileLocationPrivateFile->setText("(no file selected)");
    ui->rbCaesar->setChecked(true);
    filePrivateFile.clear();
    ui->sbCaesar->setValue(1);
}

/*!
Die Checkbox prüfen und Variablen anpassen
*/
void Widget::showOrHideTargetDestination(void)
{
    if (ui->cbSameAsSource->isChecked() == true)
    {
        fileTargetFolder = fileToBeEncrypted;
        fileTargetFolder.remove(QRegExp("[^\\]*$"));
        fileTargetFolder.remove(QRegExp("[^/]*$"));
        ui->pbOpenDestination->setEnabled(false);
        ui->LabelFileTargetFolder->setText(fileTargetFolder);
    }else{
        ui->pbOpenDestination->setEnabled(true);
        ui->LabelFileTargetFolder->setText(fileTargetFolder);
    }

    if (fileTargetFolder == "")
    {
        ui->LabelFileTargetFolder->setText("(no folder selected)");
    }
}

/*!
Mehrere Dateien öffnen - nicht in benutzung
*/
void Widget::openFiles(void)
{
    QStringList filenames = QFileDialog::getOpenFileNames(
                this,
                tr("Open Document"),
                QDir::currentPath(),
                tr("Documents (*.doc);;All files (*.*)") );
    if( !filenames.isEmpty() )
    {
        //qDebug( filenames.join(",").toAscii() );
    }
}

/*!
Das Zielverzeichnis öffnen für die Ausgabedatei.
*/
void Widget::openDir(void)
{
    QString dirname = QFileDialog::getExistingDirectory(
                this,
                tr("Select a Directory"),
                QDir::currentPath() );
    if( !dirname.isNull() )
    {
        Widget::fileTargetFolder = dirname;
        ui->LabelFileTargetFolder->setText(Widget::fileTargetFolder);
    }
}

/*!
Eine Datei speichern - nicht in benutzung
*/
void Widget::saveFile(void)
{
    QString filename = QFileDialog::getSaveFileName(
                this,
                tr("Save Document"),
                QDir::currentPath(),
                tr("Documents (*.doc)") );
    if( !filename.isNull() )
    {

    }

}

/*!
Informationen zur Caesar Verschlüsselung weitergeben
@param[in] MODE Hier wird entschieden ob ver- oder entschlüsselt wird.
@param[in] sourcetext Der Text der verschlüsselt werden soll.
*/
void Widget::ENCRtextCaesar(int MODE, QString sourcetext)
{
CryptoLib cryptolib(26,ui->sbCaesar->value(),0);
string plain = sourcetext.toLower().toStdString();

fileHandler.writeFileText(fileToBeEncrypted,MODE,cryptolib.easy_crypt(MODE, plain));


}

/*!
Informationen zur Private Key Verschlüsselung weitergeben
@param[in] source Das Quell-QByteArray mit den Daten die ver- oder entschlüsselt werden sollen.
@param[in] key Der Schlüssel.
@param[in] decr Gibt an ob ver- oder entschlüsselt wird: true für entschlüsseln, false für verschlüsseln.
*/
void Widget::ENCRbinPKey(QByteArray source, QByteArray key, int decr)
{
CryptoLib cryptolib (0,0,1);
//QString skey = "TEST123";
//key = skey.toUtf8();

fileHandler.writeFileBinary(cryptolib.ByteXOR(source,key),fileToBeEncrypted,decr);
}

/*!
Verschlüsselung starten - als Methode zum verbinden mit dem Button
*/
void Widget::ENCRstartEncrypt(void)
{
    if (ui->rbCaesar->isChecked())
    {
        this->ENCRtextCaesar(0,fileHandler.readFileText(fileToBeEncrypted));
    }
    if (ui->rbFileKey->isChecked())
    {
        this->ENCRbinPKey(fileHandler.readFileBinary(Widget::fileToBeEncrypted),fileHandler.readFileBinary(Widget::filePrivateFile),0);
    }
    if (ui->rbPrivateKey->isChecked())
    {
        QByteArray data = ui->InputPrivateKey->text().toLatin1();
        this->ENCRbinPKey(fileHandler.readFileBinary(fileToBeEncrypted),data,0 );
    }
}

/*!
Entschlüsselung starten - als Methode zum verbinden mit dem Button
*/
void Widget::ENCRstartDecrypt(void)
{
    if (ui->rbCaesar->isChecked())
    {
        this->ENCRtextCaesar(1,fileHandler.readFileText(Widget::fileToBeEncrypted));
    }
    if (ui->rbFileKey->isChecked())
    {
        this->ENCRstartEncrypt();
    }
    if (ui->rbPrivateKey->isChecked())
    {
        this->ENCRstartEncrypt();
    }
}
